using System;
using Firestarter.Test.Base;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.BO
{

    [TestFixture]
    public class TestDMClassMustHaveObjectID
    {
        [SetUp]
        public void SetupTest()
        {
            //Runs every time that any testmethod is executed
            TestUtilsDomain.SetupTest();
            BORegistry.DataAccessor = new DataAccessorInMemory();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
            TestUtilsDomain.SetupFixture();
        }

        [TearDown]
        public void TearDownTest()
        {
            //runs every time any testmethod is complete
        }

        #region DMClassMustHaveObjectID

        [Test]
        public void Test_CreateDMClassMustHaveObjectIDRule()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            IBusinessObjectRule rule = new DMClassMustHaveObjectID();
            //---------------Test Result -----------------------
            Assert.IsNotNull(rule);
            Assert.AreEqual("DMClassMustHaveObjectID", rule.Name);
            Assert.AreEqual(ErrorLevel.Warning, rule.ErrorLevel);
        }

//        [Test]
//        public void Test_CreateDMClassMustHaveObjectIDRule_WhenClassNull_ShouldRaiseError()
//        {
//            //---------------Set up test pack-------------------
//            //---------------Assert Precondition----------------
//            //---------------Execute Test ----------------------
//            try
//            {
//                new DMClassMustHaveObjectID(null);
//                Assert.Fail("expected ArgumentNullException");
//            }
//            //---------------Test Result -----------------------
//            catch (ArgumentNullException ex)
//            {
//                StringAssert.Contains("Value cannot be null", ex.Message);
//                StringAssert.Contains("dmClass", ex.ParamName);
//            }
//        }

        [Test]
        public void Test_DMClassMustHaveObjectID_FailsIfNoObjectID_AndNoSuperClass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass();
            dmClass.Properties.CreateBusinessObject();
            IBusinessObjectRule rule = new DMClassMustHaveObjectID();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmClass.ObjectIdentity);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmClass);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
            StringAssert.Contains("The Entity/Class '", rule.Message);
            StringAssert.Contains("'" + dmClass.ToString() + "'", rule.Message);
            StringAssert.Contains("' must have an ObjectID with at least one Property", rule.Message);
        }

        [Test]
        public void Test_DMClassIfNoObjectID_UseFromSuperClass()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship inheritanceRelationship = new DMInheritanceRelationship();
            DMClass superClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            superClass.CreateObjectIdentity(TestUtilsShared.CreateUnsavedValidDMProperty(superClass));
            DMClass subClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass();
            inheritanceRelationship.SuperClass = superClass;
            inheritanceRelationship.SubClass = subClass;
            subClass.Properties.CreateBusinessObject();
            IBusinessObjectRule rule = new DMClassMustHaveObjectID();
            //---------------Assert Precondition----------------
            Assert.IsNull(subClass.ObjectIdentity);
            Assert.IsNotNull(superClass.ObjectIdentity);
            Assert.Greater(superClass.ObjectIdentity.Properties.Count, 0);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(subClass);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_DMClassIfNoObjectID_UseFromSuperClass_2ndLevel()
        {
            //---------------Set up test pack-------------------
            DMClass superSuperClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            superSuperClass.CreateObjectIdentity(TestUtilsShared.CreateUnsavedValidDMProperty(superSuperClass));

            DMClass superClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            DMClass subClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass();

            DMInheritanceRelationship inheritanceRelationshipHighLevel = new DMInheritanceRelationship();
            inheritanceRelationshipHighLevel.SuperClass = superSuperClass;
            inheritanceRelationshipHighLevel.SubClass = superClass;
            
            DMInheritanceRelationship inheritanceRelationship = new DMInheritanceRelationship();
            inheritanceRelationship.SuperClass = superClass;
            inheritanceRelationship.SubClass = subClass;
            
            subClass.Properties.CreateBusinessObject();
            IBusinessObjectRule rule = new DMClassMustHaveObjectID();
            //---------------Assert Precondition----------------
            Assert.IsNull(subClass.ObjectIdentity);
            Assert.IsNull(superClass.ObjectIdentity);
            Assert.IsNotNull(superSuperClass.ObjectIdentity);
            Assert.Greater(superSuperClass.ObjectIdentity.Properties.Count, 0);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(subClass);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }



        [Test]
        public void Test_DMClassMustHaveObjectID_FailsIfHasObjectIDWithNoProp()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass();
            dmClass.Properties.CreateBusinessObject();
            dmClass.ObjectIdentity = new DMObjectIdentity();
            IBusinessObjectRule rule = new DMClassMustHaveObjectID();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmClass.ObjectIdentity);
            Assert.AreEqual(0, dmClass.ObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmClass);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
            TestUtilsShared.AssertStringNotEmpty(rule.Message, "rule.Message");
        }
        [Test]
        public void Test_DMClassMustHaveObjectID_PassesIfHasObjectIDWithOneProp()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass();
            DMProperty prop = dmClass.Properties.CreateBusinessObject();
            dmClass.ObjectIdentity = new DMObjectIdentity();
            dmClass.ObjectIdentity.Properties.Add(prop);
            IBusinessObjectRule rule = new DMClassMustHaveObjectID();
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmClass.Properties.Count);
            Assert.IsNotNull(dmClass.ObjectIdentity);
            Assert.AreEqual(1, dmClass.ObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmClass);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        #endregion
    }
}